home *** CD-ROM | disk | FTP | other *** search
- /*
- Program to demonstrate the use of multi thread A/ROSE task
-
- Written by: Anumele D. Raja
-
- Date: March 19, 1991
-
- Copyright @ Apple Computer, Inc. 1991
-
- This program opens kNumOfQueues queues and sends messages to another task
- Receives message in a completion routine sets up a flag in global area
- There is a flag for the original message and the reply.
- When all the replies have been received the program closes all the queues and quits.
- You can quit be pressing Command-.
-
- */
-
- #include <StdIO.h>
- #include <CursorCtl.h>
- #include <StdLib.h>
-
- #include "MultiThread.h"
-
- #define kNumOfQueues 16 // Number of queues including the main queueue
- enum { kFalse, kTrue };
-
- short origFlag[kNumOfQueues], replyFlag[kNumOfQueues];
- tid_type origFrom[kNumOfQueues], origTo[kNumOfQueues];
- tid_type replyFrom[kNumOfQueues], replyTo[kNumOfQueues];
- struct QueueEntry *qPtr[kNumOfQueues];
- tid_type myTID[kNumOfQueues];
-
- void CleanUp(void)
- {
- int i;
-
- for (i = 0; i < kNumOfQueues; i++) {
- if (qPtr[i]) {
- if (myTID[i]) {
- qPtr[i]->KillReceive(); // kill all outstanding receives
- qPtr[i]->CloseQueue(); // close queue if it is opened
- }
- DestroyQueue(qPtr[i]); // destory queue
- }
- }
- }
-
- void MsgRecd(struct mMessage *msgPtr)
- {
- short code;
- tid_type temp;
- short task;
-
- code = msgPtr->mCode;
- task = code >> 1;
-
- if (code & 1) { // if it is reply
- replyFlag[task] = kTrue; // set flag for reply
- replyFrom[task] = msgPtr->mFrom;
- replyTo[task] = msgPtr->mTo;
- qPtr[task]->FreeMsg(msgPtr); // queue is the queue of the original sender
- }
- else {
- if (msgPtr->mStatus < 0) { // is it an undelived message
-
- // If so set reply to true and delete the message
-
- replyFlag[task] = kTrue; // set flag for reply
- replyFrom[task] = msgPtr->mFrom;
- replyTo[task] = msgPtr->mTo;
- qPtr[task & 0x7F]->FreeMsg(msgPtr); // extract the queue number of the original sender
- }
- else {
- origFlag[task] = kTrue; // set flag for original message
- origFrom[task] = msgPtr->mFrom;
- origTo[task] = msgPtr->mTo;
- temp = msgPtr->mFrom;
- msgPtr->mFrom = msgPtr->mTo;
- msgPtr->mTo = temp;
- msgPtr->mCode |= 1; // reply code
- qPtr[msgPtr->mSData[0]]->Send(msgPtr);
- }
- }
-
- // Issue another receive
-
- qPtr[(code & 0xFF)>>1]->Receive(OS_MATCH_ALL, OS_MATCH_ALL, OS_MATCH_ALL, 0, MsgRecd);
- }
-
- main()
- {
- struct mMessage *msgPtr[kNumOfQueues];
- short i, allDone;
-
- atexit(CleanUp); // Install clean up routine
-
- // Make new queues
-
- for (i = 0; i < kNumOfQueues; i++) {
-
- // Create queues
-
- if ((qPtr[i] = CreateQueue()) == 0) {
- printf("*** Could not make a queue %d ***\n", i);
- }
- else {
- // printf("Made a queue %d with pointer %08X\n", i, qPtr[i]);
- }
- }
-
- // Open all queues
-
- for (i = 0; i < kNumOfQueues; i++) {
- if (qPtr[i]) { // If it is a valid queue
- if ((myTID[i] = qPtr[i]->OpenQueue(0)) == 0) {
- printf("*** Could not open queue %d ***\n", i);
- }
- else {
- printf("Opened queue for %d with Task ID %d\n", i, myTID[i]);
- }
- }
- }
-
- // Get a message for each queue
-
- for (i = 0; i < kNumOfQueues; i++) {
- if (qPtr[i]) { // If it is a valid queue
- if (msgPtr[i] = qPtr[i]->GetMsg()) { // Get a message
- /* printf("Message buffer for %d with TID of %d mFrom of %d at %08X\n",
- i, qPtr[i]->GetTID(), msgPtr[i]->mFrom, msgPtr);
- */
- }
- else {
- printf("Could not get a message for queue with Task ID of %d\n", qPtr[i]->GetTID());
- }
- }
- }
-
- // Now send messages and receive with completion for different threads
-
- for (i = 0; i < kNumOfQueues; i++) {
- if (msgPtr[i] && myTID[i]) { // if there is a message buffer and it is a valid task
- int dest;
-
- dest = kNumOfQueues-1-i; // Compute destination queue number (reverse order)
-
- // The following line checks if there is a valid queue entry
-
- dest = qPtr[dest] ? dest : i; // find the actual destination
- // Get TID of a different queue if it is there. Otherwise get TID of self
- msgPtr[i]->mTo = qPtr[dest]->GetTID() ? qPtr[dest]->GetTID() : 100;
- msgPtr[i]->mCode = i*2; // message code is queue number * 2 (original sender)
- msgPtr[i]->mSData[0] = dest; // destination queue number in mSData[0] (receiver)
- replyFlag[i] = kFalse; // reset reply flag for sender
- origFlag[dest] = kFalse; // reset flag so that the receiver can set it
-
- printf("Sending a message from %d to %d\n", msgPtr[i]->mFrom, msgPtr[i]->mTo);
- qPtr[i]->Send(msgPtr[i]);
-
- // Issue a receive with completion
-
- if (msgPtr[i] = qPtr[i]->Receive(OS_MATCH_ALL, OS_MATCH_ALL, OS_MATCH_ALL, 0, MsgRecd)) {
- printf("Receive call returned an error for %d\n", i);
- }
- }
- }
-
- allDone = kFalse;
-
- // Loop till all messages and replies have been received by checking the origFlag and replyFlag
-
- while (!allDone) {
- SpinCursor(1); // give a chance for the user to abort
- allDone = kTrue; // first assume all done
- for (i = 0; i < kNumOfQueues; i++) {
- if (qPtr[i]) {
- if (origFlag[i]) {
- if (origFlag[i] > 0) {
- printf("Original message received from %d to %d\n", origFrom[i], origTo[i]);
- origFlag[i] |= 0x8000; // This is to make sure we print out only once
- }
- }
- else {
- allDone = kFalse;
- }
-
- // Now check the reply flags
-
- if (replyFlag[i]) {
- if (replyFlag[i] > 0) {
- printf("Reply message received from %d to %d\n", replyFrom[i], replyTo[i]);
- replyFlag[i] |= 0x8000; // This is to make sure we print out only once
- }
- }
- else {
- allDone = kFalse;
- }
- }
- }
- }
-
- // All done clean up
-
- printf("Good Bye!\n");
- }
-